home *** CD-ROM | disk | FTP | other *** search
/ The Best of MacTutor - S…e Code for Volumes 1 to 5 / The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin / Source Code / #49 (Oct 89) / XCMDs Source < prev   
Text File  |  1989-09-12  |  5KB  |  246 lines

  1.  
  2. /**********************************/
  3. /* File: FileCopy.c                */
  4. /*                                */
  5. /* param0 = file reference num        */
  6. /*         ( file is open    )    */
  7. /* ----------------------------    */
  8. /*                                */
  9. /* IN:                            */
  10. /*    params[0]    = name of input    */
  11. /*    params[1]    = wdid of input    */
  12. /*    params[2]     = name of output    */
  13. /*    params[3]     = wdid of output    */
  14. /**********************************/
  15.  
  16. #include    <MacTypes.h>
  17. #include    <OSUtil.h>
  18. #include    <MemoryMgr.h>
  19. #include    <FileMgr.h>
  20. #include    <ResourceMgr.h>
  21. #include    <pascal.h>
  22. #include    <string.h>
  23. #include      "HyperXCMD.h"
  24. #include    "HyperUtils.h"
  25.  
  26. pascal void main( paramPtr )
  27.     XCmdBlockPtr    paramPtr;
  28. /*****************************
  29. *    params[0]    = name of input    
  30. *    params[1]    = wdid of input    
  31. *    params[2]     = name of output
  32. *    params[3]     = wdid of output
  33. *
  34. *****************************/
  35. {
  36.     OSErr        err;
  37.     short        inWD;
  38.     short        outWD;
  39.     long        temp;
  40.     Str31        errCode;
  41.     char        inFile[256];
  42.     char        outFile[256];
  43.  
  44.     paramPtr->returnValue = 0L;
  45.     
  46.     /*** (1) Get input parameters         ***/
  47.     HLock( paramPtr->params[0] );
  48.     ZeroToPas( paramPtr, *(paramPtr->params[0]), &inFile );
  49.     HUnlock( paramPtr->params[0] );
  50.     
  51.     inWD = (short)paramtoNum( paramPtr, 1 );
  52.  
  53.     HLock( paramPtr->params[2] );
  54.     ZeroToPas( paramPtr, *(paramPtr->params[2]), &outFile );
  55.     HUnlock( paramPtr->params[2] );
  56.     
  57.     outWD = (short)paramtoNum( paramPtr, 3 );
  58.     
  59.     temp = (long)CopyFile( inFile, inWD, outFile, outWD );
  60.  
  61.  
  62.     /*** Flush the output volume        ***/
  63.     err = FlushVol( 0L, 0 );
  64.     
  65.     NumToStr( paramPtr, temp, &errCode );
  66.     paramPtr->returnValue = PasToZero( paramPtr, &errCode );
  67. }
  68.  
  69. LISTING 1: CopyFile XCMD.
  70.  
  71.  
  72.  
  73. OSErr    CopyFork( inref, outref, siz )
  74.     short    inref;
  75.     short    outref;
  76.     long    siz;
  77. /*****************************
  78. * Given that the caller has opened
  79. * a fork and passed you the names of 
  80. * the input, copy the number of bytes
  81. * from the input fork to the output 
  82. * fork.
  83. *
  84. * The input mark should be set to 
  85. * start of fork.
  86. *
  87. * We use a "semi-smart" algorithm
  88. * to do the copy.  If the entire
  89. * fork can be copied, we try doing 
  90. * that, otherwise, we keep dividing
  91. * the size by two until we get enough
  92. * room to read some data in.
  93. *
  94. ******************************/
  95. {
  96.     OSErr    rd_err        = noErr;
  97.     OSErr    wrt_err        = noErr;
  98.     long        rd_len;    /*** actual bytes read ***/
  99.     Ptr        inbuf;
  100.     
  101.     /*** make sure that the size is even ***/
  102.     if( siz % 2 )
  103.         ++siz;
  104.         
  105.     if( siz > 0 ){
  106.         do{
  107.             inbuf = NewPtr( siz );
  108.             if( !inbuf )
  109.                 siz = ( siz >> 1 );
  110.                 
  111.         }while( !inbuf );
  112.     
  113.     /*** inbuf is the buffer that we     ***/
  114.     /*** read the data into. If not     ***/
  115.     /*** allocated, don't attempt to do    ***/
  116.     /*** the read                     ***/
  117.         if( inbuf ){
  118.             do{
  119.                 rd_len = siz;
  120.                 rd_err = FSRead( inref, &rd_len, inbuf );
  121.                 wrt_err= FSWrite( outref, &rd_len, inbuf );
  122.             }while( !rd_err && !wrt_err );
  123.             
  124.             DisposPtr( inbuf );
  125.         }
  126.     }
  127.     return( wrt_err );
  128. }
  129.  
  130.  
  131. OSErr    CopyFile( inFile, inWD, outFile, outWD )
  132.     char        *inFile;
  133.     short    inWD;
  134.     char        *outFile;
  135.     short    outWD;
  136. /*****************************
  137. * (1) Determine the size of the input 
  138. * file. 
  139. *
  140. * (2) Attempt to allocate that 
  141. * much space for the output file.
  142. *
  143. * (3) If allocation successful,
  144. * create the output file.
  145. *
  146. * (4) Once the file is created,
  147. * copy the data fork, the resource
  148. * fork and the finder information
  149. * from the input file.
  150. * The file will be called "copy of..."
  151. * Each time we create the file, first
  152. * see if that name exists, if so, keep
  153. * sticking "copy of" onto the name.
  154. ******************************/
  155. {
  156.     OSErr    err;
  157.     OSErr    err2;
  158.     short    inref;
  159.     short    outref;
  160.     long        data_eof    = 0L;
  161.     long        rsrc_eof    = 0L;
  162.     FInfo    fndrinfo;
  163.     
  164.     
  165.     /*** (2) Determine how big the input file is ***/
  166.     if( (err = FSOpen( inFile, inWD, &inref )) == noErr){
  167.         err = GetEOF( inref, &data_eof );
  168.         err = FSClose( inref );
  169.     }        
  170.     
  171.     if( (err = OpenRF( inFile, inWD, &inref )) == noErr ){
  172.         err = GetEOF( inref, &rsrc_eof );
  173.         err = FSClose( inref );    
  174.     }
  175.     
  176.     
  177.     /*** (2) Create  output file and allocate space***/
  178.     if( ( err = GetFInfo( inFile, inWD, &fndrinfo ) ) != noErr )
  179.         return( err );
  180.     
  181.     if( ( err = Create( outFile, inWD, fndrinfo.fdCreator, fndrinfo.fdType )) != noErr )
  182.         return( err );
  183.             
  184.     /*** (3) Try to allocate enough space for both***/
  185.     /*** forks. Note that if we get enough space. ***/
  186.         
  187.     if( (err = FSOpen( outFile, outWD, &outref )) != noErr)
  188.         return( err );
  189.     
  190.     if( (err = SetEOF( outref, data_eof  )) != noErr ){
  191.         err2 = FSClose( outref );
  192.         err2 = FSDelete( outFile, outWD );
  193.         return( err );
  194.     }
  195.  
  196.     err2     = FSClose( outref );
  197.     err     = OpenRF( outFile, outWD, &outref );
  198.     
  199.     if( (err = SetEOF( outref, rsrc_eof  )) != noErr ){
  200.         err2 = FSClose( outref );
  201.         err2 = FSDelete( outFile, outWD );
  202.         return( err );
  203.     }
  204.     err2 = FSClose( outref );
  205.  
  206.     
  207.     /*** (4) Copy the Data fork                ***/
  208.     err     = FSOpen( inFile, inWD, &inref );
  209.     
  210.     if( !err ){
  211.         err2     = SetFPos( inref, fsFromStart, 0L );
  212.         err        = CopyFork( inref, outref, data_eof );
  213.         err2     = FSClose( inref );
  214.         err2     = FSClose( outref );    
  215.     }
  216.     
  217.     if( err ){
  218.         err2 = FSDelete( outFile, outWD );
  219.         return( err );
  220.     }
  221.         
  222.     /*** (5) Now copy the resource fork        ***/
  223.     err     = OpenRF( inFile, inWD, &inref );
  224.     
  225.     if( !err ){
  226.         err2     = SetFPos( inref, fsFromStart, 0L );
  227.         err     = OpenRF( outFile, outWD, &outref );
  228.         err        = CopyFork( inref, outref, rsrc_eof );
  229.         err2     = FSClose( inref );
  230.         err2     = FSClose( outref );    
  231.     }
  232.     
  233.     if( err ){
  234.         err2 = FSDelete( outFile, outWD );
  235.         return( err );
  236.     }
  237.         
  238.     return( noErr );
  239. }
  240.  
  241.  
  242.  
  243. LISTING 2: CopyFile and CopyFork Functions.
  244.  
  245.